home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / mweb / MWEB Utils / ws295sdk.exe / Ws2sdkzp.exe / SAMPLES / LAYERED / DPROVIDE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-06  |  9.3 KB  |  343 lines

  1. /*++
  2.  
  3.      Copyright (c) 1996 Intel Corporation
  4.      Copyright (c) 1996 Microsoft Corporation
  5.      All Rights Reserved
  6.  
  7.      Permission is granted to use, copy and distribute this software and
  8.      its documentation for any purpose and without fee, provided, that
  9.      the above copyright notice and this statement appear in all copies.
  10.      Intel makes no representations about the suitability of this
  11.      software for any purpose.  This software is provided "AS IS."
  12.  
  13.      Intel specifically disclaims all warranties, express or implied,
  14.      and all liability, including consequential and other indirect
  15.      damages, for the use of this software, including liability for
  16.      infringement of any proprietary rights, and including the
  17.      warranties of merchantability and fitness for a particular purpose.
  18.      Intel does not assume any responsibility for any errors which may
  19.      appear in this software nor any responsibility to update it.
  20.  
  21.  
  22. Module Name:
  23.  
  24.     dprovide.cpp
  25.  
  26. Abstract:
  27.  
  28.     This module defines the class dprovider along with its methods.
  29.  
  30. --*/
  31.  
  32. #include "precomp.h"
  33. #include <stdlib.h>
  34.  
  35. GUID TransmitFileGuid = WSAID_TRANSMITFILE;
  36. GUID AcceptExGuid = WSAID_ACCEPTEX;
  37. GUID GetAcceptExSockAddrsGuild = WSAID_GETACCEPTEXSOCKADDRS; 
  38.  
  39.  
  40. DPROVIDER::DPROVIDER()
  41. /*++
  42. Routine Description:
  43.  
  44.     Creates any internal state.
  45.  
  46. Arguments:
  47.  
  48.     None
  49.  
  50. Return Value:
  51.  
  52.     None
  53.  
  54. --*/
  55.  
  56. {
  57.     m_proctable = NULL;
  58.     m_library_handle = NULL;
  59.     m_lib_name = NULL;
  60.     m_extensions_initialized;
  61. }
  62.  
  63.  
  64.  
  65. DPROVIDER::~DPROVIDER()
  66. /*++
  67. Routine Description:
  68.  
  69.     destroys any internal state.
  70.  
  71. Arguments:
  72.  
  73.     None
  74.  
  75. Return Value:
  76.  
  77.     None
  78.  
  79. --*/
  80. {
  81.     int ErrorCode;
  82.  
  83.  
  84.     if (m_library_handle)
  85.     {
  86.         if (m_proctable->lpWSPCleanup)
  87.         {
  88.             DEBUGF( DBG_TRACE,
  89.                     ("\nCalling WSPCleanup for provider %X", this));
  90.             //Call the servce provider cleanup routine
  91.             WSPCleanup(&ErrorCode);
  92.         } //if
  93.  
  94.         // Free the service provider DLL
  95.         FreeLibrary(m_library_handle);
  96.     } //if
  97.  
  98.     if(m_proctable){
  99.         delete m_proctable;
  100.     }
  101.     delete m_lib_name;
  102.     DEBUGF( DBG_TRACE,
  103.             ("\nDestroying provider %X", this));
  104. }
  105.  
  106.  
  107.  
  108. INT
  109. DPROVIDER::Initialize(
  110.     IN PWCHAR lpszLibFile,
  111.     IN LPWSAPROTOCOL_INFOW lpProtocolInfo
  112.     )
  113. /*++
  114. Routine Description:
  115.  
  116.     Initializes the DPROVIDER object.
  117.  
  118. Arguments:
  119.  
  120.     lpszLibFile - A  Null  terminating  string  that  points to the .DLL of the
  121.                   service to load.
  122.  
  123.     lpProtocolInfo - A pointer to a WSAPROTOCOL_INFO struct to hand to the
  124.                      provider startup routine.
  125.  
  126. Return Value:
  127.  
  128.     If no error occurs, Initialize() returns ERROR_SUCEES.  Otherwise the value
  129.     SOCKET_ERROR  is  returned,  and  a  specific  error  code  is available in
  130.     lpErrno.
  131.  
  132. --*/
  133. {
  134.     LPWSPSTARTUP        WSPStartupFunc          = NULL;
  135.     WORD                wVersionRequested       = MAKEWORD(2,2);
  136.     INT                 error_code              = 0;
  137.     WSPDATA             WSPData;
  138.     CHAR                LibraryPath[MAX_PATH];
  139.     CHAR                lpszLibFileA[MAX_PATH];
  140.  
  141.     DEBUGF( DBG_TRACE,
  142.             ("\nInitializing provider %X", this));
  143.  
  144.     m_proctable = new WSPPROC_TABLE;
  145.     if(!m_proctable){
  146.         DEBUGF(
  147.             DBG_ERR,
  148.             ("\nFailed to allocate WSPPROC_TABLE for provider object"));
  149.         return WSA_NOT_ENOUGH_MEMORY;
  150.     }
  151.  
  152.     // Zero out contents of m_proctable
  153.     ZeroMemory(
  154.         (PVOID) m_proctable,      // Destination
  155.         sizeof(LPWSPPROC_TABLE)); // Length
  156.  
  157.  
  158.     //
  159.     // Expand the library name to pickup environment/registry variables
  160.     //
  161.     wcstombs (lpszLibFileA, lpszLibFile, MAX_PATH);
  162.     if (!( ExpandEnvironmentStrings(lpszLibFileA,
  163.                                     LibraryPath,
  164.                                     MAX_PATH))){
  165.         DEBUGF(
  166.             DBG_ERR,
  167.             ("\nExpansion of environment variables failed"));
  168.         return WSASYSCALLFAILURE;
  169.     } //if
  170.  
  171.     
  172.     m_lib_name = new char[strlen(LibraryPath)+1];
  173.  
  174.     strcpy(m_lib_name,LibraryPath);
  175.  
  176.     
  177.     //
  178.     // First load the DLL for the service provider. Then get two functions that
  179.     // init the service provider structures.
  180.     //
  181.     m_library_handle = LoadLibrary(LibraryPath);
  182.     if(!m_library_handle){
  183.         DEBUGF(
  184.             DBG_ERR,
  185.             ("\nFailed to load DLL %s",LibraryPath));
  186.         return  WSAEPROVIDERFAILEDINIT;
  187.     }
  188.  
  189.     WSPStartupFunc = (LPWSPSTARTUP)GetProcAddress(
  190.         m_library_handle,
  191.         "WSPStartup"
  192.         );
  193.  
  194.     if(!(WSPStartupFunc)){
  195.  
  196.         DEBUGF( DBG_ERR,("\nCould get startup entry point for %s",
  197.                          lpszLibFile));
  198.         return  WSAEPROVIDERFAILEDINIT;
  199.     }
  200.  
  201. #if !defined(DEBUG_TRACING)
  202.     error_code = (*WSPStartupFunc)(
  203.         wVersionRequested,
  204.         & WSPData,
  205.         lpProtocolInfo,
  206.         gUpCallTable,
  207.         m_proctable);
  208. #else
  209.     { // declaration block
  210.         LPWSPDATA  pWSPData = & WSPData;
  211.         BOOL       bypassing_call;
  212.  
  213.         bypassing_call = PREAPINOTIFY((
  214.             DTCODE_WSPStartup,
  215.             & error_code,
  216.             LibraryPath,
  217.             & wVersionRequested,
  218.             & pWSPData,
  219.             & lpProtocolInfo,
  220.             gUpCallTable,
  221.             m_proctable));
  222.         if (! bypassing_call) {
  223.             error_code = (*WSPStartupFunc)(
  224.                 wVersionRequested,
  225.                 & WSPData,
  226.                 lpProtocolInfo,
  227.                 gUpCallTable,
  228.                 m_proctable);
  229.             POSTAPINOTIFY((
  230.                 DTCODE_WSPStartup,
  231.                 & error_code,
  232.                 LibraryPath,
  233.                 & wVersionRequested,
  234.                 & pWSPData,
  235.                 & lpProtocolInfo,
  236.                 gUpCallTable.lpWPUCloseEvent,
  237.                 m_proctable->lpWSPAccept));
  238.         } // if ! bypassing_call
  239.     } // declaration block
  240. #endif // !defined(DEBUG_TRACING)
  241.  
  242.     if(ERROR_SUCCESS != error_code){
  243.         DEBUGF(DBG_ERR, ("\nWSPStartup for %s Failed",lpszLibFile));
  244.         return error_code;
  245.     }
  246.  
  247.     //
  248.     // Make sure that all of the procedures at least have a non null pointer.
  249.     //
  250.     if( !m_proctable->lpWSPAccept              ||
  251.         !m_proctable->lpWSPAddressToString     ||
  252.         !m_proctable->lpWSPAsyncSelect         ||
  253.         !m_proctable->lpWSPBind                ||
  254.         !m_proctable->lpWSPCancelBlockingCall  ||
  255.         !m_proctable->lpWSPCleanup             ||
  256.         !m_proctable->lpWSPCloseSocket         ||
  257.         !m_proctable->lpWSPConnect             ||
  258.         !m_proctable->lpWSPDuplicateSocket     ||
  259.         !m_proctable->lpWSPEnumNetworkEvents   ||
  260.         !m_proctable->lpWSPEventSelect         ||
  261.         !m_proctable->lpWSPGetOverlappedResult ||
  262.         !m_proctable->lpWSPGetPeerName         ||
  263.         !m_proctable->lpWSPGetSockName         ||
  264.         !m_proctable->lpWSPGetSockOpt          ||
  265.         !m_proctable->lpWSPGetQOSByName        ||
  266.         !m_proctable->lpWSPIoctl               ||
  267.         !m_proctable->lpWSPJoinLeaf            ||
  268.         !m_proctable->lpWSPListen              ||
  269.         !m_proctable->lpWSPRecv                ||
  270.         !m_proctable->lpWSPRecvDisconnect      ||
  271.         !m_proctable->lpWSPRecvFrom            ||
  272.         !m_proctable->lpWSPSelect              ||
  273.         !m_proctable->lpWSPSend                ||
  274.         !m_proctable->lpWSPSendDisconnect      ||
  275.         !m_proctable->lpWSPSendTo              ||
  276.         !m_proctable->lpWSPSetSockOpt          ||
  277.         !m_proctable->lpWSPShutdown            ||
  278.         !m_proctable->lpWSPSocket              ||
  279.         !m_proctable->lpWSPStringToAddress ){
  280.  
  281.         DEBUGF(DBG_ERR,
  282.                ("\nService provider %s returned an invalid procedure table",
  283.                 lpszLibFile));
  284.         return WSAEINVALIDPROCTABLE;
  285.     }
  286.  
  287.     //
  288.     // Confirm that the WinSock service provider supports 2.0. If it supports a
  289.     // version greater then 2.0 it will still return 2.0 since this is the
  290.     // version  we requested.
  291.     //
  292.     if(WSPData.wVersion != MAKEWORD(2,2)){
  293.         if(m_proctable->lpWSPCleanup) {
  294.             if(m_proctable->lpWSPCleanup(&error_code)){
  295.                 DEBUGF( DBG_ERR,
  296.                         ("\nService Provider %s does not support version 2.2",
  297.                          lpszLibFile));
  298.                 return WSAVERNOTSUPPORTED;
  299.             }
  300.         }
  301.         return WSAEINVALIDPROVIDER;
  302.     }
  303.  
  304.     return ERROR_SUCCESS;
  305. } //Initailize
  306.  
  307.  
  308. INT
  309. DPROVIDER::InterceptExtensions (
  310.     IN LPVOID        lpvInBuffer,
  311.     OUT LPVOID        lpvOutBuffer,
  312.     OUT LPINT        lpErrno
  313.     )
  314. {
  315.     INT    ReturnValue=NO_ERROR;
  316.  
  317.     if (memcmp (lpvInBuffer,
  318.                 &TransmitFileGuid,
  319.                 sizeof (GUID))==0) {
  320.         m_transmitfile = *((LPFN_TRANSMITFILE *)lpvOutBuffer);
  321.         *((LPFN_TRANSMITFILE *)lpvOutBuffer) = WSPTransmitFile;
  322.     }
  323.     else if (memcmp (lpvInBuffer,
  324.                 &AcceptExGuid,
  325.                 sizeof (GUID))==0) {
  326.         m_acceptex = *((LPFN_ACCEPTEX *)lpvOutBuffer);
  327.         *((LPFN_ACCEPTEX *)lpvOutBuffer) = WSPAcceptEx;
  328.     }
  329.     else if (memcmp (lpvInBuffer,
  330.                 &GetAcceptExSockAddrsGuild,
  331.                 sizeof (GUID))==0)
  332.         // No translation required because no socket handle is
  333.         // involved in this call
  334.         ;
  335.     else {
  336.         ReturnValue = SOCKET_ERROR;
  337.         *lpErrno = WSAEOPNOTSUPP;
  338.     }
  339.  
  340.     return ReturnValue;
  341. }
  342.  
  343.